//---CREDITS
//	Name:	Types.hpp
//	Desc:	Common types and macros
//	Tabs: tabbed at 3
//------------------------------>
#ifndef ___RSLIB_TYPES___
#define ___RSLIB_TYPES___



//---COMPILER
//------------------------>
#ifdef __GNUC__
	#ifndef RS_GCC_COMPILER 
	#define RS_GCC_COMPILER __GNUC__
	#endif
#endif 
#ifdef _MSC_VER
	#ifndef RS_VC_COMPILER 
	#define RS_VC_COMPILER _MSC_VER
	#endif
#endif
 
 
 
//---PLATFORM
//---------------------->
#ifdef WIN32
	#ifndef WINDOWS
	#define WINDOWS
	#endif
	
	#ifndef RS_WINDOWS
	#define RS_WINDOWS
	#endif
	
	#ifndef FORCEINLINE
	#define FORCEINLINE __forceinline
	#endif
#endif

 
 
#ifdef __linux
	#ifndef LINUX
	#define LINUX
	#endif
	#ifndef RS_LINUX
	#define RS_LINUX
	#endif
	
	#ifndef FORCEINLINE
	#define FORCEINLINE inline
	#endif
#endif
 
 
 
//---BUILD
//-------------------------->
#if defined(_DEBUG)
	#define RS_DEBUG_BUILD
#endif
 
 
 
//---ASSERTION
//------------------------>
#if defined(RS_DEBUG_BUILD)
	#define RS_ASSERT(expression) _ASSERTE(expression)
#else
	#define RS_ASSERT(expression) (void)(0)
#endif
 
 
 
//---TYPES & DEFINES
//	Note:	Some of these types are defined exactly the same in windows
//------------------------------------------------------------------>
typedef char						CHAR8,*PCHAR8;
typedef signed char				INT8,*PINT8;
typedef unsigned char			UINT8,*PUINT8,BYTE,*PBYTE;
#ifdef _NATIVE_WCHAR_T_DEFINED
typedef wchar_t					CHAR16,*PCHAR16;
#else
	#ifdef __wchar_t
		typedef __wchar_t					CHAR16,*PCHAR16;
	#else
		typedef unsigned short			CHAR16,*PCHAR16;
	#endif	
#endif
typedef signed short				INT16,*PINT16;
typedef unsigned short			UINT16,*PUINT16,WORD,*PWORD;
typedef signed int				INT32,*PINT32;
typedef unsigned int				UINT32,*PUINT32,FLAGS32,*PFLAGS32;
typedef unsigned long			BOOL32,*PBOOL32;
typedef unsigned long			DWORD,*PDWORD;
typedef float						FLT32,*PFLT32;
typedef double						FLT64,*PFLT64;
typedef void						*PVOID;
typedef unsigned long int		PTR32,*PPTR32;

 
#ifdef RS_WINDOWS
typedef signed __int64			INT64, *PINT64;
typedef unsigned __int64		UINT64, *PUINT64,QWORD,*PQWORD;
#endif
 
 
#define VIRTUAL virtual


//---WINDOWS DUPLICATES
//	Note: do not change. they are defined exactly in this way inside windows headers
//--------------------------------------------------------------------------------->
#define PURE = 0
#define NULL 0

#define FALSE   0
#define TRUE    1

//windows.h contains this whole block...
//so defining VOID alone would leave undefined CHAR,SHORT and LONG
//creating a deadly tragedy if this header is thrown in before windows.h
#ifndef VOID
	#define VOID void
	typedef char CHAR;
	typedef short SHORT;
	typedef long LONG;
#endif

#ifndef _WINERROR_
	typedef LONG HRESULT;
	#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
	#define FAILED(Status) ((HRESULT)(Status)<0)
#endif
 
 
//---MACROS & TEMPLATES
//-------------------------------------------------------------------->
#define ARRAY_ITEMS(array)					(sizeof(array)/sizeof(array[0]))
#define ARRAY_BYTES(array)					(sizeof(array))
#define CAST(type,expression)				((type)(expression))
#define SEEAS(type,object)					(*(type*)(void*)&(object))
#define REFERABLE_AS(type) 				(RSLib::ReferableTempObject<type>)
#define UNREFERENCED_PARAM(x)				x
#define BRES_TO_URES(bRes)					((bRes) ? 0x0000000 : 0x80000000)
 
 
 
namespace RSLib {

template<class T,class O> T& SeeAs(O& o){return *(T*)&o;}
template <typename T> class ReferableTempObject
{
	public:
	T x;
	
	public:
	ReferableTempObject(T t){x = t;}
	
	public:
	operator T&(){return x;}
};


}//namespace RSLib

 
 
//---PARAMETERS TYPE
//------------------->
#define IN
#define OUT


//---EXCEPTION HANDLING
//--------------------->
#define BEGINTRYBLOCK try{
#define BEGINCATCHBLOCK(x) }catch(x){
#define ENDCATCHBLOCK }
 

#define ABS(a) ( (a)> 0  ? (a) : (-(a)) )
#define MIN(a,b) ( (a)<(b) ? (a) : (b) )
#define MAX(a,b) ( (a)>(b) ? (a) : (b) )
#define MAX3(a,b,c) (MAX(MAX(a,b),c))
#define MIN3(a,b,c) (MIN(MIN(a,b),c))
#define CLAMP(x,a,b) ((x) < (a)? (a) : ( (x) > (b) ? (b) : (x) ) )
 
 
 
//---INPLACE CONSTRUCTOR & DESTRUCTOR
//	Samp:	CONSTRUCT(Vector3,normal);
//			CONSTRUCT(Vector3,normal)(1,1,1);
//			DESTRUCT(Vector3,normal);
//	Note:	pointer conversion added to catch class mismatching
//---------------------------------------------------------->
#define CONSTRUCT(class,object) new ((class*)&(object)) class
#define DESTRUCT(class,object) (object).~class()
 
 
 
//---ASSEMBLY CODING
//----------------------------->
#define BEGIN_ASSEMBLY __asm {
#define ASSEMBLY __asm
#define END_ASSEMBLY }
 
 
#endif//___RSLIB_TYPES___
